import "dart:core";

typedef NodeId = String;
typedef EndpointId = int;
typedef AttributeId = int;
typedef ClusterId = int;
typedef EventId = int;
typedef CommandId = int;

/// MethodType websocket通信消息类型
enum MethodType {
  unknown(name: "unknown"),
  statusResponse(name: "status.response"),
  readRequest(name: "read.attribute"),
  readResponse(name: "read.attribute.response"),
  reportAttribute(name: "report.attribute"),
  reportEvent(name: "report.event"),
  writeRequest(name: "write.attribute"),
  writeResponse(name: "write.response"),
  invokeRequest(name: "invoke.request"),
  invokeResponse(name: "invoke.response");

  const MethodType({required this.name});
  final String name;

  static MethodType byName(String name) {
    for (var value in MethodType.values) {
      if (value.name == name) {
        return value;
      }
    }
    return MethodType.unknown;
  }
}

// DeviceType nova物模型定义的设备类型，沿用matter的设备类型
enum DeviceType {
  unknown(id: 0xffff, name: "Unknown"),
  rootNode(id: 0x0016, name: "RootNode"),
  aggregator(id: 0x000E, name: "Aggregator"),
  bridgedNode(id: 0x0013, name: "BridgedNode"),
  loOnOff(id: 0x0100, name: "OnOff"),
  loOnOffSwitch(id: 0x0103, name: "Switch"),
  dimmableLight(id: 0x0101, name: "DimmableLight"),
  colorLight(id: 0x010D, name: "ColorLight"),
  occupancySensor(id: 0x0107, name: "OccupancySensor"),
  temperatureSensor(id: 0x0302, name: "TemperatureSensor"),
  humiditySensor(id: 0x0307, name: "HumiditySensor"),
  thermostat(id: 0x0301, name: "Thermostat"),
  fan(id: 0x002B, name: "Fan"),
  contactSensor(id: 0x0015, name: "ContactSensor");

  const DeviceType({required this.id, required this.name});

  final int id;
  final String name;

  static DeviceType byId(int id) {
    for (var value in DeviceType.values) {
      if (value.id == id) {
        return value;
      }
    }
    return DeviceType.unknown;
  }
}

/// StatusCode 状态码，参照matter协议
enum StatusCode {
  success(value: 0x00, name: "Success"),
  failure(value: 0x01, name: "Failure"),
  unsupportedEndpoint(value: 0x7f, name: "UnsupportedEndpoint"),
  unknown(value: 0xff, name: "Unknown");

  const StatusCode({required this.value, required this.name});
  final int value;
  final String name;

  static StatusCode byValue(int value) {
    for (var item in StatusCode.values) {
      if (item.value == value) return item;
    }
    return StatusCode.unknown;
  }
}

extension EndpointIds on EndpointId {
  static EndpointId get empty => 0xffff;
  static EndpointId get rootNode => 0;
}

extension ClusterIds on ClusterId {
  static ClusterId get onOff => 0x0006;
  static ClusterId get levelControl => 0x0008;
  static ClusterId get colorControl => 0x0300;
  static ClusterId get thermostat => 0x0201;
  static ClusterId get fanControl => 0x0202;
  static ClusterId get occupancySensing => 0x0406;
  static ClusterId get booleanState => 0x0045;
  static ClusterId get temperatureMeasurement => 0x0402;
  static ClusterId get relativeHumidityMeasurement => 0x0405;
  static ClusterId get descriptor => 0x001D;
  static ClusterId get basicInformation => 0x0028;
  static ClusterId get meshProvisioner => 0xFF01;
  static ClusterId get zigbeeCoordinator => 0xFF02;
  static ClusterId get bridgedDeviceBasicInformation => 0x0039;
  static ClusterId get empty => 0xffffffff;
}

extension AttributeIds on AttributeId {
  static AttributeId get empty => 0xffff;
}

extension OnOffAttributeIds on AttributeId {
  static AttributeId get onOff => 0x0000;
}

extension BasicInformationAttributeIds on AttributeId {
  static AttributeId get reachable => 0x0011;
}

extension LevelControlAttributeIds on AttributeId {
  static AttributeId get currentLevel => 0x0000;
}

extension MeasurementAttributeIds on AttributeId {
  static AttributeId get measuredValue => 0x0000;
  static AttributeId get minMeasuredValue => 0x0001;
  static AttributeId get maxMeasuredValue => 0x0002;
}

extension ColorControlAttributeIds on AttributeId {
  static AttributeId get currentHue => 0x0000;
  static AttributeId get currentSaturation => 0x0001;
  static AttributeId get colorTemperatureMireds => 0x0007;
  static AttributeId get colorMode => 0x0008;
  static AttributeId get colorCapabilities => 0x400A;
  static AttributeId get colorTempPhysicalMinMireds => 0x400B;
  static AttributeId get colorTempPhysicalMaxMireds => 0x400C;
  static AttributeId get coupleColorTempToLevelMinMireds => 0x400D;
}

enum ColorCapability {
  colorTemperature(id: 0x10, value: "ColorTemperature"),
  colorLoop(id: 0x04, value: "ColorLoop"),
  hueSaturation(id: 0x01, value: "HueSaturation");

  final int id;
  final String value;

  const ColorCapability({required this.id, required this.value});

  static ColorCapability? byValue(String value) {
    for (var item in ColorCapability.values) {
      if (item.value == value) return item;
    }
    return null;
  }
}

enum ColorMode {
  hueAndSaturation(id: 0x00, name: "颜色"),
  colorTemperature(id: 0x02, name: "色温");

  final int id;
  final String name;
  const ColorMode({required this.id, required this.name});

  static ColorMode? byValue(int id) {
    for (var item in ColorMode.values) {
      if (item.id == id) return item;
    }
    return null;
  }
}

extension OccupancySensingAttributeIds on AttributeId {
  static AttributeId get occupancy => 0x0000;
  static AttributeId get occupancySensorType => 0x0001;
  static AttributeId get occupancySensorTypeBitmap => 0x0002;
}

extension BooleanStateAttributeIds on AttributeId {
  static AttributeId get stateValue => 0x0000;
}

extension ThermostatAttributeIds on AttributeId {
  static AttributeId localTemperature = 0x0000;
  static AttributeId outdoorTemperature = 0x0001;
  static AttributeId coolingSetPoint = 0x0011;
  static AttributeId heatingSetPoint = 0x0012;
  static AttributeId systemMode = 0x001C;
}

extension FanAttributeId on AttributeId {
  static AttributeId fanMode = 0x0000;
  static AttributeId fanSetting = 0x0002;
  static AttributeId fanCurrent = 0x0003;
}

enum AirConditionerSystemMode {
  off(name: "关机", value: 0x00),
  auto(name: "自动", value: 0x01),
  cool(name: "制冷", value: 0x03),
  heat(name: "制热", value: 0x04),
  dry(name: "除湿", value: 0x07),
  fanOnly(name: "送风", value: 0x08);

  const AirConditionerSystemMode({required this.value, required this.name});
  final int value;
  final String name;

  static AirConditionerSystemMode? byValue(int value) {
    for (var item in AirConditionerSystemMode.values) {
      if (item.value == value) return item;
    }
    return null;
  }
}